home *** CD-ROM | disk | FTP | other *** search
- { IMAGES.P -- image procecssing routines }
- { All images must be decompressed first! }
-
- { Copyright (c) 1987, Ciarcia's Circuit Cellar }
- { All Rights Reserved }
-
- {-------------------------------------------------------}
- { Do pic1 + pic2 into pic3 }
- { Sticks at maxbit }
-
- PROCEDURE Add(pic1,pic2,pic3 : picptr);
-
- VAR
- lndx : linerng; { line number }
- pndx : pelrng; { pel number }
- pelval : INTEGER; { pel value }
-
- BEGIN
-
- FOR lndx := 0 TO maxline DO
- FOR pndx := 0 TO maxpel DO BEGIN
- pelval := pic1^.fmt.lines[lndx].pels[pndx] +
- pic2^.fmt.lines[lndx].pels[pndx];
- IF pelval > maxbit
- THEN pic3^.fmt.lines[lndx].pels[pndx] := maxbit
- ELSE pic3^.fmt.lines[lndx].pels[pndx] := pelval;
- END;
- END;
-
-
- {-------------------------------------------------------}
- { Do pic1 - pic2 into pic3 }
- { Sticks at zero for pic1 < pic2 }
-
- PROCEDURE Subtract(pic1,pic2,pic3 : picptr);
-
- VAR
- lndx : linerng; { line number }
- pndx : pelrng; { pel number }
-
- BEGIN
-
- FOR lndx := 0 TO maxline DO
- FOR pndx := 0 TO maxpel DO
- IF pic1^.fmt.lines[lndx].pels[pndx] >=
- pic2^.fmt.lines[lndx].pels[pndx]
- THEN pic3^.fmt.lines[lndx].pels[pndx] :=
- pic1^.fmt.lines[lndx].pels[pndx] -
- pic2^.fmt.lines[lndx].pels[pndx]
- ELSE pic3^.fmt.lines[lndx].pels[pndx] := 0;
-
- END;
-
-
- {-------------------------------------------------------}
- { Do pic1 masked by pic2 into pic3 }
- { Only pic1 pels at non-zero pic2 pels go to pic3 }
-
- PROCEDURE Mask(pic1,pic2,pic3 : picptr);
-
- VAR
- lndx : linerng; { line number }
- pndx : pelrng; { pel number }
-
- BEGIN
-
- FOR lndx := 0 TO maxline DO
- FOR pndx := 0 TO maxpel DO
- IF pic2^.fmt.lines[lndx].pels[pndx] <> 0
- THEN pic3^.fmt.lines[lndx].pels[pndx] :=
- pic1^.fmt.lines[lndx].pels[pndx]
- ELSE pic3^.fmt.lines[lndx].pels[pndx] := 0;
-
- END;
-
-
- {-------------------------------------------------------}
- { Do Abs(pic1 - pic2) into pic3 }
- { Detects changes in images }
-
- PROCEDURE Compare(pic1,pic2,pic3 : picptr);
-
- VAR
- lndx : linerng; { line number }
- pndx : pelrng; { pel number }
-
- BEGIN
-
- FOR lndx := 0 TO maxline DO
- FOR pndx := 0 TO maxpel DO
- pic3^.fmt.lines[lndx].pels[pndx] := Abs(
- pic1^.fmt.lines[lndx].pels[pndx] -
- pic2^.fmt.lines[lndx].pels[pndx]);
-
- END;
-
-
- {-------------------------------------------------------}
- { Add a constant to pic1 }
-
- PROCEDURE Offset(pic1 : picptr;
- newoffs : BYTE);
-
- VAR
- lndx : linerng; { line number }
- pndx : pelrng; { pel number }
- pelval : INTEGER; { pel value }
-
- BEGIN
-
- FOR lndx := 0 TO maxline DO
- FOR pndx := 0 TO maxpel DO BEGIN
- pelval := newoffs + pic1^.fmt.lines[lndx].pels[pndx];
- IF (pelval AND $FFC0) = 0
- THEN pic1^.fmt.lines[lndx].pels[pndx] := pelval
- ELSE pic1^.fmt.lines[lndx].pels[pndx] := maxbit;
- END;
-
- END;
-
-
- {-------------------------------------------------------}
- { Multiply pic1 by a value }
- { Sticks at maximum value }
-
- PROCEDURE Multiply(pic1 : picptr;
- newscale : REAL);
-
- VAR
- lndx : linerng; { line number }
- pndx : pelrng; { pel number }
- pelval : INTEGER; { pel value }
-
- BEGIN
-
- FOR lndx := 0 TO maxline DO
- FOR pndx := 0 TO maxpel DO BEGIN
- pelval := Trunc(newscale * pic1^.fmt.lines[lndx].pels[pndx]);
- IF (pelval AND $FFC0) = 0
- THEN BEGIN
- pic1^.fmt.lines[lndx].pels[pndx] := pelval;
- END
- ELSE BEGIN
- pic1^.fmt.lines[lndx].pels[pndx] := maxbit;
- END;
- END;
-
- END;
-
-
- {-------------------------------------------------------}
- { Threshold pic1 at a brightness level }
-
- PROCEDURE Threshold(pic1 : picptr;
- level : BYTE);
-
- VAR
- lndx : linerng; { line number }
- pndx : pelrng; { pel number }
-
- BEGIN
-
- FOR lndx := 0 TO maxline DO
- FOR pndx := 0 TO maxpel DO
- IF pic1^.fmt.lines[lndx].pels[pndx] < level
- THEN pic1^.fmt.lines[lndx].pels[pndx] := 0;
-
- END;
-
-
- {-------------------------------------------------------}
- { Invert pel values }
-
- PROCEDURE Invert(pic1 : picptr);
-
- VAR
- lndx : linerng; { line number }
- pndx : pelrng; { pel number }
-
- BEGIN
-
- FOR lndx := 0 TO maxline DO
- FOR pndx := 0 TO maxpel DO
- pic1^.fmt.lines[lndx].pels[pndx] := maxbit AND
- (NOT pic1^.fmt.lines[lndx].pels[pndx]);
-
- END;
-
-
- {-------------------------------------------------------}
- { Filter by averaging vertical and horizontal neighbors }
-
- PROCEDURE Filter1(pic1,pic2 : picptr);
-
- VAR
- lndx : linerng; { line number }
- pndx : pelrng; { pel number }
-
- BEGIN
-
- FOR lndx := 1 TO (maxline-1) DO
- FOR pndx := 1 TO (maxpel-1) DO
- pic2^.fmt.lines[lndx].pels[pndx] :=
- (pic1^.fmt.lines[lndx-1].pels[pndx] +
- pic1^.fmt.lines[lndx+1].pels[pndx] +
- pic1^.fmt.lines[lndx].pels[pndx-1] +
- pic1^.fmt.lines[lndx].pels[pndx+1])
- SHR 2;
-
- END;
-
-
- {-------------------------------------------------------}
- { Edge detection }
-
- PROCEDURE Edge(pic1,pic2 : picptr);
-
- VAR
- lndx : linerng; { line number }
- pndx : pelrng; { pel number }
-
- BEGIN
-
- FOR lndx := 1 TO (maxline-1) DO
- FOR pndx := 1 TO (maxpel-1) DO
- pic2^.fmt.lines[lndx].pels[pndx] :=
- (Abs(pic1^.fmt.lines[lndx-1].pels[pndx] -
- pic1^.fmt.lines[lndx+1].pels[pndx]) +
- Abs(pic1^.fmt.lines[lndx].pels[pndx-1] -
- pic1^.fmt.lines[lndx].pels[pndx+1]) +
- Abs(pic1^.fmt.lines[lndx-1].pels[pndx-1] -
- pic1^.fmt.lines[lndx+1].pels[pndx+1]) +
- Abs(pic1^.fmt.lines[lndx+1].pels[pndx-1] -
- pic1^.fmt.lines[lndx-1].pels[pndx+1]))
- SHR 2;
-
- END;
-
-
- {-------------------------------------------------------}
- { Compute intensity histogram for pic1 }
- { Histogram bins are REAL to avoid problems over 32K }
-
- PROCEDURE Histogram(pic1 :picptr;
- VAR histo : histtype);
-
- VAR
- hndx : bitrng; { histogram bin number }
- lndx : linerng; { line number }
- pndx : pelrng; { pel number }
-
- BEGIN
-
- FOR hndx := 0 TO maxbit DO { reset histogram }
- histo[hndx] := 0;
-
- FOR lndx := 0 TO maxline DO
- FOR pndx := 0 TO maxpel DO
- histo[pic1^.fmt.lines[lndx].pels[pndx]] :=
- histo[pic1^.fmt.lines[lndx].pels[pndx]] + 1.0;
-
- END;
-
-
- {-------------------------------------------------------}
- { Display histogram on screen }
- { Truncates longest bar to give better resolution for }
- { the rest of the bins }
-
- PROCEDURE ShowHist(histogram : histtype);
-
- CONST
- barchar = $DB; { display char for bar }
- halfbar = $DC; { half length bar }
- maxbar = 20; { length of longest bar }
-
- VAR
- binID : INTEGER;
- maxval : REAL; { the largest bin value }
- maxval1 : REAL; { the next largest bin }
- barbase : REAL; { bottom of bar }
- barmid : REAL; { middle of bar }
- barstep : REAL; { height of steps }
- halfstep : REAL; { half of barstep }
- barctr : INTEGER; { character within bar }
-
- BEGIN
-
- maxval := 1.0; { find largest value }
- maxval1 := maxval;
- binID := 0;
- FOR binID := 0 TO maxbit DO BEGIN
- IF histogram[binID] > maxval
- THEN BEGIN { new all-time high? }
- maxval1 := maxval; { save previous high }
- maxval := histogram[binID]; { set new high }
- END
- ELSE IF histogram[binID] > maxval1 { 2nd highest? }
- THEN maxval1 := histogram[binID];
- END;
-
- barstep := maxval1 / maxbar; { steps between lines }
- halfstep := barstep / 2.0; { half of one step }
-
- FOR barctr := maxbar DOWNTO 1 DO BEGIN { down bars }
- barbase := Trunc(barstep * barctr);
- barmid := barbase + halfstep;
- Write(barbase:6:0);
- FOR binID := 0 TO maxbit DO { for each bin }
- IF histogram[binID] > barmid
- THEN Write(Chr(barchar))
- ELSE IF histogram[binID] > barbase
- THEN Write(Chr(halfbar))
- ELSE Write('_');
- Writeln; { new line }
- END;
-
- Write(' 0');
- FOR binID := 0 TO maxbit DO { fill in bottom }
- IF histogram[binID] > halfstep
- THEN Write(Chr(barchar))
- ELSE IF histogram[binID] > 0
- THEN Write(Chr(halfbar))
- ELSE Write('_');
- Writeln;
-
-
- Writeln(' 0 1 2 3 ' +
- '4 5 6 ');
- Writeln(' 0123456789012345678901234567890123456789' +
- '012345678901234567890123');
-
- END;
-
-
- {-------------------------------------------------------}
- { Count pels above given brightness level }
-
- FUNCTION CountPels(pic1 : picptr;
- level : BYTE) : REAL;
-
- VAR
- lndx : linerng; { line number }
- pndx : pelrng; { pel number }
- npels : REAL; { number of pels }
-
- BEGIN
-
- npels := 0.0;
-
- FOR lndx := 0 TO maxline DO
- FOR pndx := 0 TO maxpel DO
- IF pic1^.fmt.lines[lndx].pels[pndx] >= level
- THEN npels := npels + 1.0;
-
- CountPels := npels; { set return value }
-
- END;
-
-
- {-------------------------------------------------------}
- { Return the minimum value for pic1 }
-
- FUNCTION Minpel(pic1 : picptr) : BYTE;
-
- VAR
- lndx : linerng; { line number }
- pndx : pelrng; { pel number }
- minval : BYTE; { minimum pel value }
-
- BEGIN
-
- minval := $FF;
-
- FOR lndx := 0 TO maxline DO
- FOR pndx := 0 TO maxpel DO
- IF pic1^.fmt.lines[lndx].pels[pndx] < minval
- THEN minval := pic1^.fmt.lines[lndx].pels[pndx];
-
- Minpel := minval;
-
- END;